<template>
  <div class="fx-time-picker" :class="{focus:timePickerDropdownShow,top:timePickerTop}"
       ref="timePickerDom" @click="timePickerClick">
    <div class="time-picker-input">
      <i class="iconfont icon-time fs12"/>
      <input v-model="timePickerFormat[0]" ref="startInputDom" type="text" @focus="timePickerDropdownShow=true">
      <span class="rang">至</span>
      <input v-model="timePickerFormat[1]" ref="endInputDom" type="text" @focus="timePickerDropdownShow=true">
    </div>
    <div class="time-picker-dropdown" ref="timePickerDropdownDom" v-if="timePickerDropdownShow">
      <div class="content">
        <fx-picker-item title="开始时间" time="start" :time-format="timePickerFormat"></fx-picker-item>
        <fx-picker-item title="结束时间" time="end" :time-format="timePickerFormat"></fx-picker-item>
      </div>
      <div class="footer">
        <fx-button type="text" @click.stop="timePickerCancelClick">取消</fx-button>
        <fx-button type="text" class="ml20" @click.stop="timePickerDefineClick">确定</fx-button>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, onBeforeMount, PropType, provide, ref, SetupContext, watch } from 'vue'
import { dateFormat } from '@/base/utils'
import { setDropdownPosition, useClickBlank } from '@/base/hooks'
import mitt, { Emitter } from 'mitt'

interface HandleScrollParam {
  index: string,
  timeType: 'hour' | 'min' | 'sec',
  type: 'start' | 'end'
}

interface TimePickerProps {
  modelValue: Array<Date | string>
}

export default defineComponent({
  name: 'FTimePicker',
  props: {
    modelValue: {
      type: Array as PropType<Array<Date | string>>,
      required: true
    }
  },
  emits: ['update:modelValue', 'change'],
  setup (props: TimePickerProps, ctx: SetupContext) {
    const timePickerMitt: Emitter = mitt()
    provide('timePickerMittEmit', timePickerMitt.emit)
    const oldValue = [...props.modelValue]
    const currentValue = ref<Array<Date | string>>(props.modelValue)
    const timePickerFormat = ref<string[]>([])

    watch(() => props.modelValue, (val: Array<Date | string>): void => {
      currentValue.value = val
    }, { deep: true })
    watch(currentValue.value, (val: Array<Date | string>) => {
      timePickerFormat.value[0] = dateFormat('hh:mm:ss', val[0])
      timePickerFormat.value[1] = dateFormat('hh:mm:ss', val[1])
    }, {
      deep: true,
      immediate: true
    })

    const timePickerDom = ref<HTMLElement>()
    const timePickerDropdownDom = ref<HTMLElement>()
    const startInputDom = ref<HTMLElement>()
    const endInputDom = ref<HTMLElement>()
    const timePickerTop = ref<boolean>(false)
    const timePickerDropdownShow = ref<boolean>(false)
    useClickBlank(timePickerDom, timePickerDropdownShow)

    const changeTime = (val: HandleScrollParam, index: number) => {
      const currentDate = dateFormat('YYYY-MM-DD', currentValue.value[index])
      const dateArr = timePickerFormat.value[index].split(':')
      if (val.timeType === 'hour') dateArr[0] = val.index
      if (val.timeType === 'min') dateArr[1] = val.index
      if (val.timeType === 'sec') dateArr[2] = val.index
      currentValue.value[index] = new Date(currentDate + ' ' + dateArr.join(':'))
    }

    const handleScrollSelect = (val: HandleScrollParam | undefined): void => {
      if (val) changeTime(val, val.type === 'start' ? 0 : 1)
    }
    // 处理滚动条进入
    const handleScrollEnter = (val: Omit<HandleScrollParam, 'index'> | undefined): void => {
      if (!startInputDom.value || !endInputDom.value) return
      // eslint-disable-next-line
      const currentDom: any = val?.type === 'start' ? startInputDom.value : endInputDom.value
      const start = val?.timeType === 'hour' ? 0 : val?.timeType === 'min' ? 3 : 6
      const end = start + 2
      currentDom.select()
      currentDom.selectionStart = start
      currentDom.selectionEnd = end
    }

    const handlePosition = (): void => {
      setDropdownPosition(timePickerDom, timePickerDropdownDom, timePickerTop)
    }

    watch(timePickerDropdownShow, (val: boolean): void => {
      if (!val) {
        document.removeEventListener('scroll', handlePosition, true)
      } else {
        document.addEventListener('scroll', handlePosition, true)
      }
    })

    const timePickerClick = (): void => {
      timePickerDropdownShow.value = true
      setTimeout(handlePosition)
    }

    const timePickerCancelClick = (): void => {
      currentValue.value = oldValue
      timePickerDropdownShow.value = false
    }

    const timePickerDefineClick = (): void => {
      ctx.emit('update:modelValue', currentValue.value)
      timePickerDropdownShow.value = false
    }

    onBeforeMount(() => {
      timePickerMitt.on('scrollSelect', handleScrollSelect)
      timePickerMitt.on('scrollEnter', handleScrollEnter)
    })

    return {
      currentValue,
      timePickerTop,
      timePickerFormat,
      startInputDom,
      endInputDom,
      timePickerDom,
      timePickerDropdownDom,
      timePickerDropdownShow,
      timePickerClick,
      timePickerDefineClick,
      timePickerCancelClick
    }
  }
})
</script>
